﻿//#include "FITKPSGo.h"
//// #include "CSession.h"
//#include <parasolid_kernel.h>
//#include "frustrum_ifails.h"
//#include "frustrum_tokens.h"
//#include <QDebug>
//#include <vtkUnstructuredGrid.h>
//#include <vtkIntArray.h>
//#include <vtkPoints.h>
//#include <vtkCellData.h>
//#include <vtkIdList.h>
//#include <vtkCellType.h>
//
//
//namespace PS
//{
//    inline double *VectorAdd(const double *x, const double *y, double *z)
//    {
//        z[0] = x[0] + y[0];
//        z[1] = x[1] + y[1];
//        z[2] = x[2] + y[2];
//        return z;
//    }
//
//    inline double VectorDot(const double *x, const double *y)
//    {
//        return x[0] * y[0] + x[1] * y[1] + x[2] * y[2];
//    }
//
//    inline double *VectorSubtract(const double *x, const double *y, double *z)
//    {
//        z[0] = x[0] - y[0];
//        z[1] = x[1] - y[1];
//        z[2] = x[2] - y[2];
//        return z;
//    }
//
//    inline double *VectorMult(const double *x, double m, double *y)
//    {
//        y[0] = x[0] * m;
//        y[1] = x[1] * m;
//        y[2] = x[2] * m;
//        return y;
//    }
//
//    inline double *VectorNormalise(double *x)
//    {
//        return VectorMult(x, 1.0 / sqrt(VectorDot(x, x)), x);
//    }
//
//    inline double *VectorCross(const double *x, const double *y, double *z)
//    {
//        z[0] = x[1] * y[2] - x[2] * y[1];
//        z[1] = x[2] * y[0] - x[0] * y[2];
//        z[2] = x[0] * y[1] - x[1] * y[0];
//        return z;
//    }
//
//    struct GridDataStruct
//    {
//        vtkUnstructuredGrid* _gridData;
//        vtkPoints* _points;
//
//        GridDataStruct()
//        {
//            _gridData = nullptr;
//            _points = nullptr;
//        }
//
//        //将Parasolid中的三角面片转化为vtk的三角形单元，添加至vtk非结构网格数据中
//        void addTri(const double *position, int tag)
//        {
//            vtkIdList *ids = vtkIdList::New();
//            for (int i = 0; i < 3; ++i)
//            {
//                int pid = _points->InsertNextPoint(position[i * 3 + 0], position[i * 3 + 1], position[i * 3 + 2]);
//                ids->InsertNextId(pid);
//            }
//            _gridData->InsertNextCell(VTK_TRIANGLE, ids);
//            //	tagArray->InsertNextTuple1(tag);
//        }
//
//        //添加两个点的线段
//        void addLine(const double *position, int tag)
//        {
//            vtkIdList *ids = vtkIdList::New();
//
//            int pid1 = _points->InsertNextPoint(position[0], position[1], position[2]);
//            int pid2 = _points->InsertNextPoint(position[3], position[4], position[5]);
//            ids->InsertNextId(pid1);
//            ids->InsertNextId(pid2); // ids->InsertNextId(pid1);
//
//            _gridData->InsertNextCell(VTK_LINE, ids);
//            //	tagArray->InsertNextTuple1(tag);
//        }
//
//        //添加多个点的线段
//        void addPolyLine(const int ngeo, const double *position, int tag)
//        {
//            vtkIdList *ids = vtkIdList::New();
//
//            for (int i = 0; i < ngeo; i++)
//            {
//                int pid1 = _points->InsertNextPoint(position[i * 3 + 0], position[i * 3 + 1], position[i * 3 + 2]);
//                ids->InsertNextId(pid1);
//            }
//            _gridData->InsertNextCell(VTK_POLY_LINE, ids);
//            //		tagArray->InsertNextTuple1(tag);
//        }
//
//        //添加圆锥
//        void addEllipse(const double *centre, const double *majorAxis,
//            const double *minorAxis, double majorRadius,
//            double minorRadius, const double *start, const double *end, int tag)
//        {
//            const double twopi = 3.141592654 * 2.0;
//
//            // maximum number of line segments in ellipse is defined below
//
//            const int maxSegs = 100;
//
//            // First de-parameterise the start & end point to get the start & end parameters
//            // Then x = majorAxis * majorRadius * cos( x ) + minoraxis * minorRadius * sin( x )
//
//            double param1, param2;
//
//            if (start == NULL || end == NULL)
//            {
//                param1 = 0.0;
//                param2 = twopi;
//            }
//            else
//            {
//                double vec[3];
//                VectorSubtract(start, centre, vec);
//                double cosval = VectorDot(vec, majorAxis) / majorRadius;
//                if (cosval > 1.0)
//                {
//                    cosval = 1.0;
//                }
//                if (cosval < -1.0)
//                {
//                    cosval = -1.0;
//                }
//                param1 = acos(cosval);
//                if (VectorDot(vec, minorAxis) < 0.0)
//                    param1 = twopi - param1;
//
//                VectorSubtract(end, centre, vec);
//                cosval = VectorDot(vec, majorAxis) / majorRadius;
//                if (cosval > 1.0)
//                {
//                    cosval = 1.0;
//                }
//                if (cosval < -1.0)
//                {
//                    cosval = -1.0;
//                }
//                param2 = acos(cosval);
//                if (VectorDot(vec, minorAxis) < 0.0)
//                    param2 = twopi - param2;
//
//                if (param2 < param1)
//                    param2 += twopi;
//            }
//
//            // Work out no. of segs that we want.
//
//            int nSegs = int(floor((param2 - param1) / twopi * maxSegs));
//            nSegs = nSegs > 1 ? nSegs : 1;
//            double majComp[3];
//            double minComp[3];
//            double loc[3];
//            vtkIdList *ids = vtkIdList::New();
//            for (int i = 0; i <= nSegs; i++)
//            {
//                double t = param1 + ((param2 - param1) * i) / nSegs;
//                VectorMult(majorAxis, majorRadius * cos(t), majComp);
//                VectorMult(minorAxis, minorRadius * sin(t), minComp);
//                VectorAdd(centre, majComp, loc);
//                VectorAdd(loc, minComp, loc);
//                int pid = _points->InsertNextPoint(loc[0], loc[1], loc[2]);
//                ids->InsertNextId(pid);
//            }
//            _gridData->InsertNextCell(VTK_POLY_LINE, ids);
//            //		tagArray->InsertNextTuple1(tag);;
//        }
//
//        //添加椭圆
//        void addCircle(const double *centre, const double *normal, double radius,
//            const double *start, const double *end, int tag)
//        {
//            double majAxis[3];
//            double minAxis[3];
//
//            if (start == NULL || end == NULL)
//            {
//                PK_VECTOR1_t vec, vec2, vec3;
//                for (int i = 0; i < 3; i++)
//                {
//                    vec.coord[i] = normal[i];
//                    vec2.coord[i] = 0.0;
//                }
//                VectorNormalise(vec.coord); // PK_VECTOR_perpendicular is very fussy about this.
//                PK_VECTOR_perpendicular(vec, vec2, &vec3);
//                for (int i = 0; i < 3; i++)
//                    majAxis[i] = vec3.coord[i];
//            }
//            else
//            {
//                VectorSubtract(start, centre, majAxis);
//                VectorNormalise(majAxis);
//            }
//            VectorCross(normal, majAxis, minAxis);
//            addEllipse(centre, majAxis, minAxis, radius, radius, start, end, tag);
//        }
//
//        //初始化
//        void init()
//        {
//            _gridData = vtkUnstructuredGrid::New();
//            _points = vtkPoints::New();
//            _gridData->SetPoints(_points);
//            /*		auto cells = vtkCellArray::New();
//                    GridData->SetCells(cells);*/
//
//                    // 		tagArray = vtkIntArray::New();
//                    // 		tagArray->SetName("Tag");
//                    // 		GridData->GetCellData()->AddArray(tagArray);
//        }
//
//    } Segment;
//
//    FITKPSGo::FITKPSGo()
//    {
//        PK_SESSION_ask_fru_o_t old_fru;
//
//        PK_GOSGMT_f_t m_old_gosgmt = NULL;
//        PK_GOOPSG_f_t m_old_goopsg = NULL;
//        PK_GOCLSG_f_t m_old_goclsg = NULL;
//
//        PK_SESSION_ask_fru_o_m(old_fru);
//
//        old_fru.gosgmt = &m_old_gosgmt;
//        old_fru.goopsg = &m_old_goopsg;
//        old_fru.goclsg = &m_old_goclsg;
//
//        PK_SESSION_ask_fru_2(&old_fru);
//
//        // Register the new graphics frustrum function pointers
//
//        PK_GOSGMT_f_t new_gosgmt = CoutputSegment;
//        PK_GOOPSG_f_t new_goopsg = CopenSegment;
//        PK_GOCLSG_f_t new_goclsg = CcloseSegment;
//
//        PK_SESSION_register_fru_o_t new_fru;
//        PK_SESSION_register_fru_o_m(new_fru);
//        new_fru.gosgmt = &new_gosgmt;
//        new_fru.goopsg = &new_goopsg;
//        new_fru.goclsg = &new_goclsg;
//
//        PK_SESSION_register_fru_2(&new_fru);
//    }
//
//    FITKPSGo::~FITKPSGo()
//    {
//    }
//
//    void FITKPSGo::begainGO()
//    {
//        Segment.init();
//    }
//
//    vtkDataSet *FITKPSGo::getOutput()
//    {
//        return Segment._gridData;
//    }
//
//    void FITKPSGo::CoutputSegment(const int *segtyp, const int *ntags, const int *tags,
//        const int *ngeoms, const double *geoms,
//        const int *nlntp, const int *lntp, int *ifail)
//    {
//        *ifail = CONTIN;
//
//        switch (*segtyp)
//        {
//        case SGTPFT:
//            if (lntp[2] == 1 && lntp[3] == 3)
//            {
//                switch (lntp[1]) // type of facet.
//                {
//                case L3TPFV: // Facet (no normals)
//                    *ifail = ABORT;
//                    break;
//                case L3TPFN: // facet with normals
//                    Segment.addTri(geoms, *tags);
//                    break;
//                default:
//                    *ifail = ABORT;
//                }
//            }
//            break;
//
//        case SGTPED:
//
//            switch (lntp[1])
//            {
//            case L3TPSL: // straight line
//                Segment.addLine(geoms, *tags);
//                break;
//            case L3TPPY: // poly-line
//                Segment.addPolyLine(*ngeoms, geoms, *tags);
//                break;
//            case L3TPCC:
//                Segment.addCircle(geoms, geoms + 3, geoms[6], NULL, NULL, *tags);
//                break;
//            case L3TPCI:
//                Segment.addCircle(geoms, geoms + 3, geoms[6], geoms + 7, geoms + 10, *tags);
//                break;
//            case L3TPCE: // complete ellipse
//                Segment.addEllipse(geoms, geoms + 3, geoms + 6, geoms[9], geoms[10], NULL, NULL, *tags);
//                break;
//            case L3TPEL: // elliptical arc
//                Segment.addEllipse(geoms, geoms + 3, geoms + 6, geoms[9], geoms[10], geoms + 11, geoms + 14, *tags);
//                break;
//            default:
//                qDebug() << "Line Type error : " << lntp[1] << endl;
//                *ifail = ABORT;
//                break;
//            }
//        }
//
//        //	qDebug() << "out";
//    }
//
//    void FITKPSGo::CcloseSegment(const int *segtyp, const int *ntags, const int *tags,
//        const int *ngeoms, const double *geoms,
//        const int *nlntp, const int *lntp, int *ifail)
//    {
//        *ifail = CONTIN;
//        //	qDebug() << "close";
//    }
//
//    void FITKPSGo::CopenSegment(const int *segtyp, const int *ntags, const int *tags,
//        const int *ngeoms, const double *geoms,
//        const int *nlntp, const int *lntp, int *ifail)
//    {
//        *ifail = CONTIN;
//        //	qDebug() << "open";
//    }
//
//}